package com.sls.game.supply.deal;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.util.PropertiesUtil;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.common.DeductionRefund;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsSupplyManageDAO;
import com.sls.game.parser.ParseYunRespInfo;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.pojo.yunen.YunEnRespInfo;

public class YunEnTradeDeal {

	private static Logger log = Logger.getLogger(YunEnTradeDeal.class);
	private static String filename = "yunen.properties";

	/**
	 * 交易处理
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param paymentOrderNo
	 * @param orderTime
	 * @param head
	 * @param goodsOrderDAO
	 * @param goodsSupplyManageDAO
	 * @param downstreamUserDAO
	 * @param mechantIP
	 * @return
	 */
	public static String dealTradeResultOfYun(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String paymentOrderNo,
			String orderTime, Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			DownstreamUserDAO downstreamUserDAO, String mechantIP) {
		YunEnRespInfo resInfo = trade(info, originalGoodsId, orderId,
				paymentOrderNo, head, goodsOrderDAO, goodsSupplyManageDAO,
				downstreamUserDAO, mechantIP);

		// 返回给上层对象
		SLSHttpInterfaceInfo sLSHttpInterfaceInfo = new SLSHttpInterfaceInfo();
		if (resInfo != null) {
			String result = resInfo.getOrderStatus();
			if ("UNDERWAY".equals(result)) { // 处理中
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_UNDERWAY");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else if ("SUCCESS".equals(result)) {
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_SUCCESS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else if ("ORDER_FAILURE".equals(result)
					|| "FAILURE".equals(result)
					|| "REQUEST_FAILURE".equals(result)) {
				sLSHttpInterfaceInfo.setResMsg("FAILED");
				sLSHttpInterfaceInfo.setFailedCode("208");
				sLSHttpInterfaceInfo.setFailedReason("充值失败");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_FAILED");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);

				GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
				DeductionRefundInfo dedInfo = null;
				String paymentStatus = "";
				// 退款
				dedInfo = DeductionRefund.invokeDeductRefund(info, orderId,
						"1", orderTime, paymentOrderNo, head, goodsOrderDAO);
				if (dedInfo != null) {
					paymentStatus = dedInfo.getPaymentStatus();
				}
				if ("1".equals(paymentStatus)) { // 成功
					goodsOrderInfo.setIsPay("3"); // 退款成功
					// 退款成功，通知下游用户
					DeductionRefund.noticeUserRefundMsg(orderId, dedInfo,
							goodsOrderDAO, downstreamUserDAO, null);

				} else if ("2".equals(paymentStatus)) {
					goodsOrderInfo.setIsPay("2"); // 退款失败
				}
				try {
					// 更新订单
					updateGoodsOrder(orderId, goodsOrderInfo, goodsOrderDAO,
							head);
				} catch (Exception e) {
					log.error("请求ID：" + head.getRequestId() + "根据退款状态更新订单异常！",
							e);
				}
			} else { // 存疑
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setFailedCode("210");
				sLSHttpInterfaceInfo.setFailedReason("订单存疑");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			}
		} else {
			sLSHttpInterfaceInfo.setResMsg("SUCCESS");
			sLSHttpInterfaceInfo.setFailedCode("210");
			sLSHttpInterfaceInfo.setFailedReason("订单存疑");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);
		}
		sLSHttpInterfaceInfo.setGameAccount(info.getGameAccount());
		sLSHttpInterfaceInfo.setUnitPrice(info.getUnitPrice());
		sLSHttpInterfaceInfo.setBuyNum(info.getBuyNum());

		String totalPrice = info.getTotalPrice();
		sLSHttpInterfaceInfo.setTotalPrice(totalPrice);
		Gson gson = CommonUtil.gson();
		String resultBody = gson.toJson(sLSHttpInterfaceInfo);

		return resultBody;
	}

	private static YunEnRespInfo trade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String paymentOrderNo,
			Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			DownstreamUserDAO downstreamUserDAO, String mechantIP) {
		String address = PropertiesUtil.getValue(
				"yunen.interface.recharge.address", filename);
		String merchant_id = PropertiesUtil.getValue("yunen.merchant.id",
				filename);
		GoodsOrderInfo orderInfo = new GoodsOrderInfo();
		orderInfo.setRegisterAccount(merchant_id);
		updateGoodsOrder(orderId, orderInfo, goodsOrderDAO, head);

		Map<String, String> map = assembleParameterOfTrade(info,
				originalGoodsId, orderId, mechantIP);
		// 发送http请求
		YunEnRespInfo resInfo = sendHttpRequestOfDirectTrade(address, map, head);
		// 上游订单结果
		String orderResult = "";
		String msg = "";
		String yunOrderId = "";
		String successTime = "";
		String status = "2";
		if (resInfo != null) {
			// 订单结果
			orderResult = resInfo.getOrderStatus();
			msg = resInfo.getFailedReason();
			yunOrderId = resInfo.getYunenOrderId();
			if ("SUCCESS".equals(orderResult)) { // 成功
				status = "1";
				successTime = resInfo.getOrderSuccessTime();
			} else if ("UNDERWAY".equals(orderResult)) { // 订单状态处理中
				status = "2";
			} else if ("ORDER_FAILURE".equals(orderResult)
					|| "FAILURE".equals(orderResult)
					|| "REQUEST_FAILURE".equals(orderResult)) {
				status = "0"; // 失败
			} else {
				status = "3"; // 存疑
			}
		} else {
			status = "3"; // 存疑
		}

		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setStatusRemark(msg);
		goodsOrderInfo.setSupOrderId(yunOrderId);
		goodsOrderInfo.setSupOrderSuccessTime(successTime);
		try {
			// 根据交易返回的结果更新订单表
			updateGoodsOrder(orderId, goodsOrderInfo, goodsOrderDAO, head);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "根据云恩返回的结果更新订单异常！", e);
		}
		return resInfo;
	}

	private static void updateGoodsOrder(String orderId,
			GoodsOrderInfo goodsOrderInfo, GoodsOrderDAO goodsOrderDAO,
			Head head) {
		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setSynOrAsy("0"); // 同步通知标识
		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "更新工号异常！", e);
		}
	}

	private static YunEnRespInfo sendHttpRequestOfDirectTrade(String address,
			Map<String, String> map, Head head) {
		YunEnRespInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		try {
			log.info("请求ID：" + head.getRequestId() + "，发送到云恩的直充请求参数为："
					+ address + map);
			String xmlStr = httpClient.doPost(address, map);
			log.info("请求ID：" + head.getRequestId() + "，云恩直充返回的结果参数为：" + xmlStr);
			// 对返回的xml格式字符串数据进行解析
			if (StringUtils.isNotEmpty(xmlStr)) {
				resInfo = ParseYunRespInfo.getInfoOfRecharge(xmlStr);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "云恩直充交易请求异常！", e);
		}
		return resInfo;
	}

	private static Map<String, String> assembleParameterOfTrade(
			SLSHttpInterfaceInfo info, String originalGoodsId, String orderId,
			String mechantIP) {
		Map<String, String> map = new HashMap<String, String>();
		String platformId = PropertiesUtil.getValue("yunen.platform.id",
				filename);
		String md5key = PropertiesUtil.getValue("yunen.md5.key", filename);
		String version = PropertiesUtil.getValue("yunen.version", filename);
		String merchant_id = PropertiesUtil.getValue("yunen.merchant.id",
				filename);
		String sub_mch_id = "";
		String customer = info.getGameAccount();
		String recharge_account_type = "";
		String amount = info.getBuyNum();
		String section1 = "";
		String section2 = "";
		String region = "000000";
		StringBuilder sb = new StringBuilder();
		sb.append("amount=");
		sb.append(amount);
		sb.append("&");
		map.put("amount", amount);
		sb.append("customer=");
		sb.append(customer);
		sb.append("&");
		map.put("customer", customer);
		if (StringUtils.isNotEmpty(mechantIP)) {
			sb.append("customer_ip=");
			sb.append(mechantIP);
			sb.append("&");
			map.put("customer_ip", mechantIP);
		}
		sb.append("merchant_id=");
		sb.append(merchant_id);
		sb.append("&");
		map.put("merchant_id", merchant_id);
		map.put("outer_order_id", orderId);
		sb.append("outer_order_id=");
		sb.append(orderId);
		sb.append("&");

		sb.append("platform_id=");
		sb.append(platformId);
		sb.append("&");
		map.put("platform_id", platformId);
		sb.append("product_id=");
		sb.append(originalGoodsId);
		sb.append("&");
		map.put("product_id", originalGoodsId);
		if (StringUtils.isNotEmpty(recharge_account_type)) {
			sb.append("recharge_account_type=");
			sb.append(recharge_account_type);
			sb.append("&");
			map.put("recharge_account_type", recharge_account_type);
		}
		sb.append("region=");
		sb.append(region);
		sb.append("&");
		map.put("region", region);
		if (StringUtils.isNotEmpty(sub_mch_id)) {
			sb.append("sub_mch_id=");
			sb.append(sub_mch_id);
			sb.append("&");
			map.put("sub_mch_id", sub_mch_id);
		}
		if (StringUtils.isNotEmpty(section1)) {
			sb.append("section1=");
			sb.append(section1);
			sb.append("&");
			map.put("section1", section1);
		}
		if (StringUtils.isNotEmpty(section2)) {
			sb.append("section2=");
			sb.append(section2);
			sb.append("&");
			map.put("section2", section2);
		}
		sb.append("key=");
		sb.append(md5key);
		String sign = UtilMD5Encryption.createMD5Encryption(sb.toString());
		map.put("sign", sign);
		map.put("version", version);

		return map;
	}

}
